package me.boger.venusplayer.media

import android.content.Context
import android.net.Uri
import android.view.SurfaceView
import org.videolan.libvlc.IVLCVout
import org.videolan.libvlc.LibVLC
import org.videolan.libvlc.Media
import org.videolan.libvlc.MediaPlayer
import timber.log.Timber
import java.io.FileDescriptor

/**
 * Created by hb.chen on 2017/10/11.
 */
class MediaWorkerImpl : IMediaWorker {

    private var mLibVLC: LibVLC? = null
    private var mMediaPlayer: MediaPlayer? = null
    private var mVoutCallback: IVLCVout.Callback? = null
    private var mSurfaceView: SurfaceView? = null

    override fun create(context: Context,
                        surfaceView: SurfaceView,
                        eventListener: MediaPlayer.EventListener,
                        voutCallback: IVLCVout.Callback) {
        Timber.d("create")
        surfaceView.holder.setKeepScreenOn(true)
        val libVLC = LibVLC(context, getOptions())
        val mp = MediaPlayer(libVLC)
        mp.setEventListener(eventListener)
        val vout = mp.vlcVout
        vout.addCallback(voutCallback)
        mVoutCallback = voutCallback
        mMediaPlayer = mp
        mLibVLC = libVLC
        mSurfaceView = surfaceView
    }

    override fun destroy() {
        Timber.d("destroy")
        val mp = mMediaPlayer ?: return
        val libVLC = mLibVLC ?: return
        val voutCallback = mVoutCallback ?: return
        mp.stop()
        val vout = mp.vlcVout
        vout.removeCallback(voutCallback)
        vout.detachViews()
        libVLC.release()
        mp.release()

        mMediaPlayer = null
        mLibVLC = null
        mVoutCallback = null
        mSurfaceView = null
    }

    override fun testPlay(fd: FileDescriptor) {
        val mp = mMediaPlayer ?: return
        val libVLC = mLibVLC ?: return
        if (mp.isPlaying || mp.isReleased) {
            Timber.w("the media has playing or released!")
            return
        }
        val media = Media(libVLC, fd)
        mp.media = media
        mp.play()
    }

    override fun play(uri: Uri) {
        val mp = mMediaPlayer ?: return
        val libVLC = mLibVLC ?: return
        if (mp.isPlaying || mp.isReleased) {
            Timber.w("the media has playing or released!")
            return
        }
        val media = Media(libVLC, uri)
        mp.media = media
        mp.play()
    }

    override fun attach() {
        val mp = mMediaPlayer ?: return
        val sv = mSurfaceView ?: return
        if (mp.isReleased) {
            return
        }
        val vout = mp.vlcVout
        vout.setVideoView(sv)
        vout.attachViews()
    }

    override fun detach() {
        val mp = mMediaPlayer ?: return
        if (mp.isReleased) {
            return
        }
        mp.vlcVout.detachViews()
    }

    override fun getVLCVersion(): String? {
        return mLibVLC?.version()
    }

    private fun getOptions(): ArrayList<String> {
        val ops = ArrayList<String>(3)
        ops.add("--aout=opensles")
        ops.add("--audio-time-stretch")
        ops.add("-vvv")
        ops.add("--adaptive-use-access")
        return ops
    }
}